﻿#!/usr/bin/env python3
#! -*- conding:utf-8 -*-

#第六章 面向对象

#1).定义类
#括号里面的objec表示父类,object是所有类的父类;py3 中object科院省略
class Student(object):
	
	#构造函数,self是必须的而且不需传入
	def __init__(self,name,sex="男"):
		self.name = name
		self.sex  = sex
		#以两个下划线开头的是私有变量,实例私有和之前的模块私有有区别,模块私有函数和变量只需一个下划线
		self.__myAge=10 
		self.address = "gz";
	#类内的函数参数第一个必须是self,类内的字段必须通过self访问
	def printScore(self):
		print("%s:%s:%s" %(self.name,self.sex,self.address))
		self.__couse()
	def __couse(self):
		print(self.name,"说：我正在上课")
	
print(Student)
	
#1.实例化对象
std1 =Student("kungfu");
print(std1,std1.address)
std1.score = 97 #可以随意给实例定义字段
std1.printScore()
#2.访问限制
#以两个下划线开头的是私有变量,比如 __myAge字段,但是可以通过_Student.__myAge访问,所以说python没有严格意义的访问限制
#print(std1.__myAge)
#print(std1.__couse())

#2.)继承和多态
class Animal(object):
	def run(self):
		print("Animal is running")
	
class Dog(Animal):
	def run(self):
		super().run() #调用父类的方法
		print("Dog is running!")

Dog().run()
	
#3.)获取对象信息 type函数

def fn():
	pass;
	
import types #type模块
print("type(fn)=",type(fn),types.FunctionType)

#使用dir()
#如果要获得一个对象的所有属性和方法，可以使用dir()函数，它返回一个包含字符串的list，
myDog = Dog()
info = dir(myDog)
print("info.__doc__=",info.__doc__)

'''
for i in info:
	print('dir myDog=',i)
'''	

#三个与对象属性有关的函数 hasattr(),getattr(),setattr()
print(hasattr(myDog,"x")) #判断对象是否有属性
setattr(myDog,"x",120) #设置属性和属性值
print(getattr(myDog,"x",404)) #获取属性值,其他404参数是自定义的,如果没有则返回404

#4.)实例属性和类属性
class Car():
	make = "日产"	#这个是类属性,通过类名访问类似于静态变量,但是也可以通过实例访问,
	def __init__(self,price):
		self.price = price #这个是实例属性，只能通过实例访问
		
myCar = Car(140000)
print("1=",myCar.make) #现在访问的是类属性的值
print("2=",Car.make) #类属性的值

myCar.make="奔驰" 
print("3=",myCar.make) #现在访问的是实例属性的值,这里改变了类属性的值
print("4=",Car.make) #类属性的值,虽然上面的实例改变了类属性的值,但是只对实例有效，通过类访问的值依然不变
Car.make = "宝马"
print("5=",Car.make) #通过类修改,那么通过类访问自然也改了	
print("6=",myCar.make) #类属性改变了,实例属性还是不变,因为在创建实例的时候会拷贝一份属性给实例(即系每一个实例有一个copy)		
		
		
	
	
	
	